package middleware

import (
	"github.com/gin-gonic/gin" // 导入Gin框架，用于处理HTTP请求和中间件
	"go-blog/util"
	"strings" // 字符串处理工具，用于解析Authorization头
)

// JWTAuth 定义JWT认证中间件
// 功能：保护需要登录权限的接口，验证请求中的JWT令牌有效性
// 返回值：gin.HandlerFunc - 符合Gin框架规范的中间件函数
func JWTAuth() gin.HandlerFunc {
	// 返回一个匿名函数作为中间件的具体实现
	return func(c *gin.Context) {
		// 1. 从请求头中提取Authorization字段
		// 前端应在请求头中携带Authorization: Bearer <token>格式的认证信息
		authHeader := c.GetHeader("Authorization")
		if authHeader == "" {
			// 若Authorization头为空，说明未携带令牌，标记未登录错误
			c.Set("error", "未登录：请先登录")
			c.Abort() // 终止请求处理流程，不再调用后续的处理函数
			return
		}

		// 2. 解析Bearer Token格式
		// 按空格分割Authorization头内容，期望得到["Bearer", "<token>"]两部分
		parts := strings.SplitN(authHeader, " ", 2)
		// 校验分割结果：必须刚好两部分，且第一部分为"Bearer"
		if len(parts) != 2 || parts[0] != "Bearer" {
			c.Set("error", "Token格式错误：应为Bearer <token>")
			c.Abort() // 格式错误，终止请求
			return
		}

		// 3. 验证并解析Token
		// 调用工具包的ParseToken函数，传入提取的令牌字符串
		claims, err := util.ParseToken(parts[1])
		if err != nil {
			// 解析失败（如令牌无效、已过期等）
			c.Set("error", "Token无效或已过期")
			c.Abort() // 验证失败，终止请求
			return
		}

		// 4. 将用户信息存储到上下文
		// 验证成功后，从claims中提取用户ID和用户名，存入Gin上下文
		// 后续的处理函数可通过c.Get("user_id")获取这些信息
		c.Set("user_id", claims.UserID)
		c.Set("username", claims.Username)

		// 5. 继续处理请求
		c.Next() // 调用后续的中间件或路由处理函数
	}
}
